package gtgold;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * Generates random events along every increment in the journey
 * 
 * @author jo
 */
public class RandomEvents implements Serializable
{
        /*
         * transient prevents manager from being saved into
         * the object stream, since we don't need to save
         * an instance of GameManager upon serialization
         */
        transient private GameManager manager;
        
        private final Random gen;
        private final Map<String, Object> myData;
        
        /**
         * ...
         * @param manager
         */
        public RandomEvents(GameManager manager)
        {
        		this.gen = new Random();
                this.myData = new HashMap<String, Object>();
                this.manager = manager;
        }
        
        /**
         * Checks whether a wagon piece broke
         * @param data
         * @param moved
         */
        private void checkWagonBreakage(GameData data, boolean moved)
        {
			if (moved && data.delays.brokenPiece == null){
			    int r = gen.nextInt(256) / (1 + data.pace.index); //Broken pieces are more likely when traveling faster
			    Item i = null;
			    String name = null;
			    
			    if (r == 0) {i = Item.AXLES; name = "axle";}
			    else if (r == 1) {i = Item.TOUNGES; name = "tounge";}
			    else if (r == 2) {i = Item.WHEELS; name = "wheel";}
			    
			    if (i != null){wagonFixSub(data, i, name);}
			}
        }

        /**
         * Sub method for handling fix dialog
         * @param data
         * @param i
         * @param name
         */
		private void wagonFixSub(GameData data, Item i, String name) 
		{
	        boolean tryToFix = manager.openYesNoDialog(
	                        "A wagon " + name + " has broken. Do you wish to spend a day trying to fix it?");
	        if (tryToFix){
	                data.delays.repairingWagon = true;
	                
	                if (gen.nextInt(4) == 0 || 
	                                (data.job == Occupation.CARPENTER && gen.nextInt(4) == 0))
	                {
	                        manager.openInfoDialog("You sucessfully fixed the broken wagon part.");
	                        i = null;
	                }
	                else {
	                        manager.openInfoDialog("You were unable to fix the broken wagon part.");
	                        //Fall through to case where they need to replace it with a new part
                    }
            }
            
            data.delays.brokenPiece = i;
		}
        
    	private void theif(GameData data)
    	{
    		if (gen.nextInt(256) > 0) {return;}
    		
    		int index = gen.nextInt(Item.values().length);
			Item i = Item.values()[index];
			if (data.inventory.get(i) < 2) {return;}
		
			int amount = 1 + gen.nextInt((int)data.inventory.get(i) - 1);
			amount = 1 + gen.nextInt(amount / 2);
			
			manager.openInfoDialog("A theif has stolen " + amount + " " + i.toString() + "!");
			data.inventory.add(i, -amount);
		}        
       
        /**
         * Potentially generate a random event
         * based on probability of occurrence
         */
        public void doEvents(GameData data, boolean moved)
        {
            // Wagon is damaged, requires Y to fix. Your wagon cannot move. You must have repair part Y to fix it (where Y is a wheel, axle or tongue.) This chance is greatly reduced for carpenter.
        	checkWagonBreakage(data, moved);
                
                
	        // Severe storms, lose X days. X should be between 1 and 3. Your movement is 0, but food consumption continues for X days.
        	if (data.delays.weather == null && 
        			data.distanceLeft > 0 //Can't have weather if you're at a location
        			&& gen.nextInt(16) == 0) 
        	{
        		String[] names = {"Heavy fog", "Severe storms", "Blizzard"};
        		String w = names[gen.nextInt(names.length)];
        		int d = gen.nextInt(3) + 1;
        		
        		manager.openInfoDialog(w + ", lose " + d + " day(s).");
        		data.delays.weather = w;
        		data.delays.weatherLength = d;
        	}
	                
			// Wandering UGA grad steals X from wagon. You lose item X (if food,
			// clothes or ammo, take a random amount up to 10% of total available or
			// if a repair item, lose 1.)
			theif(data);
			
			// First Nation hunting party feels sorry for you, gives you X food. You
			// receive X pounds of food. X can vary from 10 to 100.
			if (data.inventory.get(Item.FOOD) <= 200 && gen.nextInt(159) == 0) {
				int amount = gen.nextInt(91) + 10;
				
				manager.openInfoDialog("A Native American hunting party feels sorry for you and " +
						"gave you " + amount + " pounds of food.");
				data.inventory.add(Item.FOOD, amount);
			}
			
			if (moved && gen.nextInt(data.pace.index + 2) == 0) { //finding food is less likely when traveling harder
				int amount = gen.nextInt(64);
				//Farmers are much better at foraging
				if (data.job == Occupation.FARMER) {amount += gen.nextInt(17);}
				
				if (amount >= 58){
					amount = (amount - 56)/2;
					
					manager.openInfoDialog("You found " + amount + " pound(s) of edible wild berries.");
					data.inventory.add(Item.FOOD, amount);
				}
			}
	
			// An ox has died One of your oxen has died. This chance is reduced for farmer.
			if (moved && data.inventory.get(Item.OXEN) > 0) {
				int ichance =  (data.job == Occupation.FARMER) ? 531 : 321;
				
				if (gen.nextInt(ichance) == 0){
				
					data.inventory.add(Item.OXEN, -1);
					manager.openInfoDialog("One of your oxen has died");
				}
			}
	
			// Oxen are tired Movement reduced by 1-3 miles per day. Only occurs
			// during grueling pace, or a steady pace for 10 days with no rest. This
			// chance is reduced for farmer.
			if(data.oxenTired){ data.oxenTired = moved;} //no longer tired if we're resting
			else {
				if (moved && data.pace.index > Pace.STEADY.index){
					int chance = (int)(11 * (5.0 + Math.exp(5.0 - data.pace.index)));
					
					if (data.job == Occupation.FARMER) {chance += (chance/2);} //Reduced chance for farmers
					
					if (gen.nextInt(chance) < 11) {
						data.oxenTired = true;
						manager.openInfoDialog("The oxen are tired.");
					}
				}
			}
	}
}
